# language: zh-CN
# Epic 8.3: 多租户支持
# 需求ID: REQ-008.3
# SRS需求: SRS-8.3 多租户架构支持 - 系统应支持多种多租户策略，包括共享数据库、独立Schema、独立数据库等模式，提供租户识别、数据隔离、配置管理、生命周期管理和资源监控功能
# Feature ID: F-008.3
# 用户故事: 
#   US-084: 作为SaaS开发者，我希望定义多租户数据模型，以便为不同客户提供数据隔离
#   US-085: 作为SaaS开发者，我希望支持租户识别和路由，以便正确处理多租户请求
#   US-086: 作为SaaS开发者，我希望确保数据隔离和安全，以便保护租户数据不被泄露
#   US-087: 作为SaaS开发者，我希望管理租户配置，以便为不同租户提供个性化设置
#   US-088: 作为SaaS开发者，我希望管理租户生命周期，以便自动化租户的创建和配置
#   US-089: 作为SaaS开发者，我希望支持租户数据迁移，以便在不同架构间迁移租户数据
#   US-090: 作为SaaS开发者，我希望监控租户资源使用，以便优化性能和成本

功能: 多租户支持
  为了支持SaaS应用的多租户架构
  作为SaaS应用开发者
  我希望系统提供完整的多租户支持功能

  背景:
    假设我是一个SaaS应用开发者
    并且我需要为多个客户提供服务
    并且我需要确保数据隔离和安全性
    并且我需要支持灵活的租户配置

  # US-084: 作为SaaS开发者，我希望定义多租户数据模型，以便为不同客户提供数据隔离
  场景: 租户模型定义
    假设我需要定义多租户数据模型
    当我配置租户策略时:
      """
      @tenant({
        strategy: 'schema_per_tenant', // shared_database, schema_per_tenant, database_per_tenant
        isolation: 'strict',
        identification: {
          method: 'subdomain', // subdomain, header, path, custom
          field: 'tenant_id'
        },
        configuration: {
          autoCreate: true,
          defaultSchema: 'public',
          namingPattern: 'tenant_{tenant_id}'
        }
      })
      
      entity User {
        id: string @primary
        name: string @required
        email: string @unique @tenant_scoped
        
        // 租户关联
        tenantId: string @tenant_key @hidden
        
        // 跨租户关联（如果需要）
        globalUserId: string @global_reference('GlobalUser')
      }
      
      entity Order {
        id: string @primary
        userId: string @foreign_key('User')
        amount: number @required
        
        // 自动添加租户字段
        tenantId: string @tenant_key @auto
      }
      
      // 全局实体（跨租户共享）
      @global
      entity Currency {
        id: string @primary
        code: string @unique
        name: string @required
      }
      """
    那么应该生成租户隔离的数据结构:
      """
      // 租户A的Schema
      CREATE SCHEMA tenant_a;
      
      CREATE TABLE tenant_a.users (
        id VARCHAR PRIMARY KEY,
        name VARCHAR NOT NULL,
        email VARCHAR UNIQUE,
        tenant_id VARCHAR DEFAULT 'tenant_a',
        global_user_id VARCHAR
      );
      
      CREATE TABLE tenant_a.orders (
        id VARCHAR PRIMARY KEY,
        user_id VARCHAR REFERENCES tenant_a.users(id),
        amount DECIMAL NOT NULL,
        tenant_id VARCHAR DEFAULT 'tenant_a'
      );
      
      // 全局共享表
      CREATE TABLE public.currencies (
        id VARCHAR PRIMARY KEY,
        code VARCHAR UNIQUE,
        name VARCHAR NOT NULL
      );
      """
    并且应该自动添加租户字段
    并且应该支持租户级别的唯一约束
    并且应该支持全局共享实体
    并且应该支持跨租户引用

  # US-085: 作为SaaS开发者，我希望支持租户识别和路由，以便正确处理多租户请求
  场景: 租户识别和路由
    假设我需要识别和路由租户请求
    当客户端发送请求时:
      """
      // 子域名识别
      GET https://acme.myapp.com/api/users
      
      // 请求头识别
      GET https://api.myapp.com/users
      X-Tenant-ID: acme
      
      // 路径识别
      GET https://api.myapp.com/tenants/acme/users
      
      // JWT Token识别
      GET https://api.myapp.com/users
      Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
      // JWT payload: { "sub": "user123", "tenant": "acme" }
      """
    那么应该正确识别租户:
      """
      {
        "tenantResolution": {
          "method": "subdomain",
          "tenantId": "acme",
          "tenantInfo": {
            "id": "acme",
            "name": "Acme Corporation",
            "status": "active",
            "plan": "enterprise",
            "schema": "tenant_acme",
            "database": "main",
            "features": ["advanced_analytics", "custom_branding"],
            "limits": {
              "users": 1000,
              "storage": "100GB",
              "apiCalls": 100000
            }
          },
          "context": {
            "connectionString": "postgresql://user:pass@host/db?search_path=tenant_acme",
            "cachePrefix": "acme:",
            "logContext": { "tenant": "acme" }
          }
        }
      }
      """
    并且应该设置数据库连接上下文
    并且应该配置缓存前缀
    并且应该设置日志上下文
    并且应该验证租户状态和权限

  # US-086: 作为SaaS开发者，我希望确保数据隔离和安全，以便保护租户数据不被泄露
  场景: 数据隔离和安全
    假设我需要确保租户数据隔离
    当执行数据库查询时:
      """
      // 用户查询（自动添加租户过滤）
      const users = await User.findAll({
        where: { status: 'active' }
      });
      
      // 生成的SQL（自动添加租户条件）
      SELECT * FROM tenant_acme.users 
      WHERE status = 'active' AND tenant_id = 'acme';
      
      // 跨租户查询（需要特殊权限）
      const globalStats = await User.findAll({
        crossTenant: true,
        where: { createdAt: { gte: '2024-01-01' } },
        groupBy: 'tenantId'
      });
      """
    那么应该自动应用租户过滤:
      """
      {
        "queryExecution": {
          "originalQuery": "SELECT * FROM users WHERE status = 'active'",
          "modifiedQuery": "SELECT * FROM tenant_acme.users WHERE status = 'active' AND tenant_id = 'acme'",
          "tenantContext": {
            "tenantId": "acme",
            "schema": "tenant_acme",
            "isolation": "strict"
          },
          "securityChecks": {
            "tenantAccess": "granted",
            "crossTenantAccess": "denied",
            "dataLeakagePrevention": "active"
          }
        }
      }
      """
    并且应该防止数据泄露
    并且应该支持行级安全策略
    并且应该记录数据访问审计
    并且应该支持加密存储

  # US-087: 作为SaaS开发者，我希望管理租户配置，以便为不同租户提供个性化设置
  场景: 租户配置管理
    假设我需要管理租户配置
    当配置租户设置时:
      """
      @tenantConfig({
        tenant: 'acme',
        settings: {
          branding: {
            logo: 'https://cdn.acme.com/logo.png',
            primaryColor: '#FF6B35',
            theme: 'dark'
          },
          features: {
            advancedReports: true,
            apiAccess: true,
            customFields: true,
            sso: {
              enabled: true,
              provider: 'okta',
              config: {
                domain: 'acme.okta.com',
                clientId: 'encrypted:okta_client_id'
              }
            }
          },
          limits: {
            users: 1000,
            storage: '100GB',
            apiCallsPerMonth: 1000000,
            customFields: 50
          },
          notifications: {
            email: {
              fromAddress: 'noreply@acme.com',
              templates: {
                welcome: 'acme_welcome_template'
              }
            },
            webhooks: [
              {
                event: 'user.created',
                url: 'https://acme.com/webhooks/user-created',
                secret: 'encrypted:webhook_secret'
              }
            ]
          },
          integrations: {
            payment: {
              provider: 'stripe',
              config: {
                publicKey: 'pk_test_...',
                secretKey: 'encrypted:stripe_secret'
              }
            },
            analytics: {
              provider: 'google',
              trackingId: 'GA-ACME-001'
            }
          }
        }
      })
      """
    那么应该应用租户特定配置:
      """
      {
        "tenantConfiguration": {
          "tenantId": "acme",
          "appliedSettings": {
            "ui": {
              "logo": "https://cdn.acme.com/logo.png",
              "primaryColor": "#FF6B35",
              "theme": "dark"
            },
            "features": {
              "enabled": ["advancedReports", "apiAccess", "customFields", "sso"],
              "disabled": ["whiteLabeling", "multiLanguage"]
            },
            "quotas": {
              "users": { "limit": 1000, "used": 245, "remaining": 755 },
              "storage": { "limit": "100GB", "used": "23.5GB", "remaining": "76.5GB" },
              "apiCalls": { "limit": 1000000, "used": 125000, "remaining": 875000 }
            }
          }
        }
      }
      """
    并且应该支持动态配置更新
    并且应该验证配置有效性
    并且应该支持配置继承
    并且应该支持配置版本管理

  # US-088: 作为SaaS开发者，我希望管理租户生命周期，以便自动化租户的创建和配置
  场景: 租户生命周期管理
    假设我需要管理租户生命周期
    当创建新租户时:
      """
      const newTenant = await TenantManager.create({
        id: 'newcorp',
        name: 'New Corporation',
        plan: 'professional',
        admin: {
          name: 'Admin User',
          email: 'admin@newcorp.com',
          password: 'securePassword123'
        },
        settings: {
          timezone: 'America/New_York',
          currency: 'USD',
          language: 'en'
        },
        provisioning: {
          createSchema: true,
          seedData: true,
          setupIntegrations: true
        }
      });
      """
    那么应该自动配置租户环境:
      """
      {
        "tenantProvisioning": {
          "tenantId": "newcorp",
          "status": "provisioning",
          "steps": [
            {
              "step": "create_schema",
              "status": "completed",
              "duration": "2.3s",
              "result": "Schema 'tenant_newcorp' created successfully"
            },
            {
              "step": "create_tables",
              "status": "completed",
              "duration": "1.8s",
              "result": "15 tables created"
            },
            {
              "step": "seed_data",
              "status": "in_progress",
              "progress": "60%",
              "result": "Seeding default data..."
            },
            {
              "step": "create_admin_user",
              "status": "pending"
            },
            {
              "step": "setup_integrations",
              "status": "pending"
            }
          ],
          "estimatedCompletion": "2024-01-15T10:35:00Z"
        }
      }
      """
    并且应该创建租户数据库结构
    并且应该初始化默认数据
    并且应该创建管理员用户
    并且应该配置集成服务

  # US-089: 作为SaaS开发者，我希望支持租户数据迁移，以便在不同架构间迁移租户数据
  场景: 租户数据迁移
    假设我需要迁移租户数据
    当执行租户迁移时:
      """
      @tenantMigration({
        source: {
          tenant: 'oldcorp',
          strategy: 'schema_per_tenant'
        },
        target: {
          tenant: 'newcorp',
          strategy: 'database_per_tenant'
        },
        migration: {
          mode: 'online', // online, offline, hybrid
          batchSize: 1000,
          parallelTables: 3,
          dataTransformation: {
            'users': {
              mapping: {
                'full_name': (record) => `${record.first_name} ${record.last_name}`,
                'email': (record) => record.email.toLowerCase()
              },
              filters: {
                status: 'active'
              }
            }
          },
          validation: {
            checkConstraints: true,
            verifyRowCounts: true,
            sampleDataCheck: 0.1 // 检查10%的数据
          }
        },
        rollback: {
          enabled: true,
          backupBeforeMigration: true,
          rollbackTimeout: '1 hour'
        }
      })
      """
    那么应该安全迁移租户数据:
      """
      {
        "migrationStatus": {
          "migrationId": "mig_001",
          "status": "in_progress",
          "progress": {
            "overall": 45,
            "tables": {
              "users": { "status": "completed", "rows": 1250 },
              "orders": { "status": "in_progress", "rows": 5000, "progress": 60 },
              "products": { "status": "pending" }
            }
          },
          "validation": {
            "constraintChecks": "passed",
            "rowCountVerification": "in_progress",
            "dataIntegrityCheck": "pending"
          },
          "performance": {
            "throughput": "2500 rows/second",
            "estimatedCompletion": "2024-01-15T12:30:00Z"
          }
        }
      }
      """
    并且应该支持在线迁移
    并且应该验证数据完整性
    并且应该支持回滚操作
    并且应该监控迁移进度

  # US-090: 作为SaaS开发者，我希望监控租户资源使用，以便优化性能和成本
  场景: 租户资源监控
    假设我需要监控租户资源使用
    当收集租户指标时:
      """
      @tenantMonitoring({
        metrics: {
          database: {
            connections: true,
            queryPerformance: true,
            storageUsage: true,
            indexUsage: true
          },
          application: {
            apiCalls: true,
            responseTime: true,
            errorRate: true,
            activeUsers: true
          },
          business: {
            userGrowth: true,
            featureUsage: true,
            revenue: true,
            churnRate: true
          }
        },
        alerts: {
          storageThreshold: 0.8, // 80%
          connectionThreshold: 0.9, // 90%
          errorRateThreshold: 0.05, // 5%
          responseTimeThreshold: 2000 // 2秒
        },
        reporting: {
          frequency: 'daily',
          recipients: ['admin@tenant.com', 'ops@platform.com'],
          dashboards: ['tenant_overview', 'performance_metrics']
        }
      })
      """
    那么应该收集详细的租户指标:
      """
      {
        "tenantMetrics": {
          "tenantId": "acme",
          "timestamp": "2024-01-15T10:00:00Z",
          "database": {
            "connections": {
              "active": 25,
              "max": 100,
              "utilization": 0.25
            },
            "storage": {
              "used": "23.5GB",
              "limit": "100GB",
              "utilization": 0.235,
              "growth": "+2.3GB this month"
            },
            "performance": {
              "avgQueryTime": "45ms",
              "slowQueries": 3,
              "indexHitRatio": 0.98
            }
          },
          "application": {
            "apiCalls": {
              "total": 125000,
              "limit": 1000000,
              "utilization": 0.125,
              "trend": "+15% vs last month"
            },
            "users": {
              "total": 245,
              "active": 89,
              "limit": 1000
            },
            "performance": {
              "avgResponseTime": "156ms",
              "errorRate": 0.008,
              "uptime": 0.9995
            }
          },
          "alerts": [
            {
              "level": "warning",
              "metric": "storage_usage",
              "value": 0.235,
              "threshold": 0.8,
              "message": "Storage usage is approaching limit"
            }
          ]
        }
      }
      """
    并且应该生成使用报告
    并且应该发送告警通知
    并且应该支持自动扩容
    并且应该提供成本分析

  场景: 租户计费和配额
    假设我需要管理租户计费
    当计算租户使用费用时:
      """
      @tenantBilling({
        tenant: 'acme',
        plan: {
          name: 'enterprise',
          basePrice: 299, // 月费
          currency: 'USD',
          billing: 'monthly',
          features: {
            users: { included: 100, overage: 5 }, // 超出每用户$5
            storage: { included: '50GB', overage: 0.1 }, // 超出每GB $0.1
            apiCalls: { included: 500000, overage: 0.001 }, // 超出每次调用 $0.001
            support: 'priority'
          }
        },
        usage: {
          period: '2024-01',
          users: 245,
          storage: '67.5GB',
          apiCalls: 750000,
          features: ['advancedReports', 'sso', 'customBranding']
        },
        discounts: [
          {
            type: 'annual_commitment',
            percentage: 0.15
          }
        ]
      })
      """
    那么应该计算准确的费用:
      """
      {
        "billing": {
          "tenantId": "acme",
          "period": "2024-01",
          "plan": "enterprise",
          "charges": {
            "base": {
              "amount": 299.00,
              "description": "Enterprise plan base fee"
            },
            "overages": {
              "users": {
                "included": 100,
                "used": 245,
                "overage": 145,
                "rate": 5.00,
                "amount": 725.00
              },
              "storage": {
                "included": "50GB",
                "used": "67.5GB",
                "overage": "17.5GB",
                "rate": 0.10,
                "amount": 1.75
              },
              "apiCalls": {
                "included": 500000,
                "used": 750000,
                "overage": 250000,
                "rate": 0.001,
                "amount": 250.00
              }
            },
            "features": {
              "advancedReports": 50.00,
              "sso": 100.00,
              "customBranding": 25.00
            }
          },
          "subtotal": 1450.75,
          "discounts": {
            "annual_commitment": -217.61
          },
          "total": 1233.14,
          "currency": "USD",
          "dueDate": "2024-02-01"
        }
      }
      """
    并且应该支持配额限制
    并且应该生成账单
    并且应该支持多种计费模式
    并且应该集成支付网关

  场景: 租户备份和恢复
    假设我需要备份租户数据
    当执行租户备份时:
      """
      @tenantBackup({
        tenant: 'acme',
        type: 'full', // full, incremental, differential
        schedule: {
          frequency: 'daily',
          time: '02:00',
          timezone: 'UTC',
          retention: {
            daily: 7,
            weekly: 4,
            monthly: 12
          }
        },
        storage: {
          provider: 's3',
          bucket: 'tenant-backups',
          encryption: 'AES-256',
          compression: 'gzip'
        },
        options: {
          includeBlobs: true,
          includeIndexes: true,
          includeMetadata: true,
          consistency: 'snapshot'
        },
        verification: {
          enabled: true,
          sampleRestore: true,
          integrityCheck: true
        }
      })
      """
    那么应该创建可靠的备份:
      """
      {
        "backupResult": {
          "backupId": "backup_acme_20240115_020000",
          "tenantId": "acme",
          "type": "full",
          "status": "completed",
          "startTime": "2024-01-15T02:00:00Z",
          "endTime": "2024-01-15T02:15:23Z",
          "duration": "00:15:23",
          "size": {
            "uncompressed": "2.3GB",
            "compressed": "890MB",
            "compressionRatio": 0.39
          },
          "contents": {
            "tables": 15,
            "rows": 125000,
            "indexes": 23,
            "blobs": 450,
            "metadata": "included"
          },
          "verification": {
            "integrityCheck": "passed",
            "sampleRestore": "passed",
            "checksums": "verified"
          },
          "storage": {
            "location": "s3://tenant-backups/acme/2024/01/15/backup_acme_20240115_020000.gz",
            "encryption": "AES-256",
            "retention": "2024-04-15T02:00:00Z"
          }
        }
      }
      """
    并且应该支持增量备份
    并且应该验证备份完整性
    并且应该支持自动恢复
    并且应该管理备份生命周期